package cloud.pangui.core.spring;

import org.springframework.beans.BeansException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * @author hepangui
 */
@Configuration
@Order(Integer.MIN_VALUE)
public class SpringUtils {

	private static ConfigurableApplicationContext applicationContext;

	public static void setApplicationContext(ConfigurableApplicationContext applicationContext) throws BeansException {
		SpringUtils.applicationContext = applicationContext;
	}


	/**
	 * 获取一个bean
	 * @param beanId
	 * @return
	 */
	public static Object getBean(String beanId) {
		return applicationContext.getBean(beanId);
	}

	/**
	 * 根据class获取bean
	 * @param beanClass
	 * @param <T>
	 * @return
	 */
	public static <T> T getBean(Class<T> beanClass) {
		return applicationContext.getBean(beanClass);
	}

	/**
	 * 根据注解获取bean
	 * @param annotation
	 * @return
	 */
	public static Map getBeansByAnnotation(Class annotation) {
		return applicationContext.getBeansWithAnnotation(annotation);
	}

	/**
	 * 根据类获取所有的bean
	 * @param beanClass
	 * @return
	 */
	public static List getBeansByType(Class beanClass) {
		Map beansOfType = applicationContext.getBeansOfType(beanClass);
		return (List) beansOfType.values().stream().collect(Collectors.toList());

	}

	/**
	 * 获取配置
	 * @param key
	 * @return
	 */
	public static String getProperty(String key) {
		return applicationContext.getEnvironment().getProperty(key);
	}

	/**
	 * 获取配置，并指定默认值
	 * @param key
	 * @param defaultValue
	 * @return
	 */
	public static String getProperty(String key, String defaultValue) {
		return applicationContext.getEnvironment().getProperty(key, defaultValue);
	}

	/**
	 * 判断是都存在配置
	 * @param key
	 * @return
	 */
	public static boolean hasProperty(String key) {
		return applicationContext.getEnvironment().containsProperty(key);
	}

	/**
	 * 设置自定义的配置，最高优先级
	 * @param props
	 */
	public static void putPropertys(Map<String,String> props) {
		for (Map.Entry<String, String> entry : props.entrySet()) {
			System.setProperty(entry.getKey(),entry.getValue());
		}
	}

	/**
	 * 设置自定义的配置，最高优先级
	 * @param key
	 * @param value
	 */
	public static void putProperty(String key, String value) {
		System.setProperty(key,value);
	}

	/**
	 * 获取所有配置
	 * @return
	 */
	public static Properties getProperties() {
		MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
		Properties p = new Properties();
		Iterator<PropertySource<?>> iterator = propertySources.iterator();
		while (iterator.hasNext()) {
			PropertySource<?> next = iterator.next();
			if (next instanceof MapPropertySource) {
				String[] propertyNames = ((MapPropertySource) next).getPropertyNames();
				for (String propertyName : propertyNames) {
					p.put(propertyName, next.getProperty(propertyName));
				}
			}
		}
		return p;

	}
}
